package com.ruoyi.gen.controller;

import java.util.List;
import java.util.stream.Collectors;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.gen.domain.ExternalDbConfig;
import com.ruoyi.gen.domain.GenTable;
import com.ruoyi.gen.domain.GenTableColumn;
import com.ruoyi.gen.service.ExternalDataSourceService;
import com.ruoyi.gen.service.IGenTableService;

/**
 * 外部数据库连接控制器
 * 
 * @author ruoyi
 */
@RestController
@RequestMapping("/gen/external")
public class ExternalDbController extends BaseController {

    @Autowired
    private ExternalDataSourceService externalDataSourceService;

    @Autowired
    private IGenTableService genTableService;

    /**
     * 测试外部数据库连接
     */
    @RequiresPermissions("tool:gen:list")
    @PostMapping("/testConnection")
    public AjaxResult testConnection(@Valid @RequestBody ExternalDbConfig config) {
        try {
            boolean success = externalDataSourceService.testConnection(config);
            if (success) {
                return success("连接测试成功");
            } else {
                return error("连接测试失败，请检查配置信息");
            }
        } catch (Exception e) {
            logger.error("测试数据库连接异常", e);
            return error("连接测试失败: " + e.getMessage());
        }
    }

    /**
     * 获取外部数据库表列表
     */
    @RequiresPermissions("tool:gen:list")
    @PostMapping("/tables")
    public TableDataInfo getExternalDbTables(@RequestBody ExternalDbConfig config,
            @RequestParam(value = "tableName", required = false) String tableName,
            @RequestParam(value = "tableComment", required = false) String tableComment) {
        try {
            startPage();
            List<GenTable> list = externalDataSourceService.getExternalDbTableList(config, tableName, tableComment);
            return getDataTable(list);
        } catch (Exception e) {
            logger.error("获取外部数据库表列表异常", e);
            return getDataTable(null);
        }
    }

    /**
     * 从外部数据库导入表结构
     */
    @RequiresPermissions("tool:gen:import")
    @Log(title = "代码生成", businessType = BusinessType.IMPORT)
    @PostMapping("/importTables")
    public AjaxResult importExternalTables(@RequestBody ImportExternalTablesRequest request) {
        try {
            if (request.getTableNames() == null || request.getTableNames().length == 0) {
                return error("请选择要导入的表");
            }

            // 验证数据库连接
            boolean connectionValid = externalDataSourceService.testConnection(request.getDbConfig());
            if (!connectionValid) {
                return error("数据库连接失败，请检查配置");
            }

            // 获取表结构并导入
            List<GenTable> tableList = externalDataSourceService.getExternalDbTableList(
                    request.getDbConfig(), null, null);

            // 过滤选中的表
            List<GenTable> selectedTables = tableList.stream()
                    .filter(table -> {
                        for (String tableName : request.getTableNames()) {
                            if (tableName.equals(table.getTableName())) {
                                return true;
                            }
                        }
                        return false;
                    })
                    .collect(java.util.stream.Collectors.toList());

            if (selectedTables.isEmpty()) {
                return error("未找到要导入的表");
            }

            // 为每个表获取字段信息
            for (GenTable table : selectedTables) {
                List<com.ruoyi.gen.domain.GenTableColumn> columns = externalDataSourceService.getExternalTableColumns(
                        request.getDbConfig(), table.getTableName());
                table.setColumns(columns);
            }

            // 导入表结构
            genTableService.importGenTable(selectedTables);

            return success("成功导入 " + selectedTables.size() + " 个表");

        } catch (Exception e) {
            logger.error("导入外部数据库表异常", e);
            return error("导入失败: " + e.getMessage());
        }
    }

    /**
     * 获取支持的数据库类型列表
     */
    @GetMapping("/dbTypes")
    public AjaxResult getSupportedDbTypes() {
        java.util.Map<String, Object> dbTypes = new java.util.HashMap<>();
        dbTypes.put("mysql", "MySQL");
        dbTypes.put("postgresql", "PostgreSQL");
        dbTypes.put("oracle", "Oracle");
        dbTypes.put("sqlserver", "SQL Server");

        return success(dbTypes);
    }

    /**
     * 清理临时数据源连接
     */
    @RequiresPermissions("tool:gen:list")
    @PostMapping("/cleanup")
    public AjaxResult cleanupConnections() {
        try {
            externalDataSourceService.cleanupAllDataSources();
            return success("清理完成");
        } catch (Exception e) {
            logger.error("清理数据源连接异常", e);
            return error("清理失败: " + e.getMessage());
        }
    }

    /**
     * 实时同步外部数据库表结构
     */
    @RequiresPermissions("tool:gen:import")
    @Log(title = "代码生成", businessType = BusinessType.IMPORT)
    @PostMapping("/syncTableStructure")
    public AjaxResult syncTableStructure(@RequestBody SyncTableStructureRequest request) {
        try {
            if (request.getTableNames() == null || request.getTableNames().length == 0) {
                return error("请选择要同步的表");
            }

            // 验证数据库连接
            boolean connectionValid = externalDataSourceService.testConnection(request.getDbConfig());
            if (!connectionValid) {
                return error("数据库连接失败，请检查配置");
            }

            // 获取表结构并同步到gen_table
            List<GenTable> tableList = externalDataSourceService.getExternalDbTableList(
                    request.getDbConfig(), null, null);

            // 过滤出需要同步的表
            List<GenTable> tablesToSync = tableList.stream()
                    .filter(table -> java.util.Arrays.asList(request.getTableNames()).contains(table.getTableName()))
                    .collect(java.util.stream.Collectors.toList());

            if (tablesToSync.isEmpty()) {
                return error("未找到要同步的表");
            }

            // 为每个表获取字段信息
            for (GenTable table : tablesToSync) {
                List<GenTableColumn> columns = externalDataSourceService.getExternalTableColumns(
                        request.getDbConfig(), table.getTableName());
                table.setColumns(columns);
            }

            // 检查表是否已存在，如果存在则更新，否则新增
            List<String> existingTables = new java.util.ArrayList<>();
            List<GenTable> newTables = new java.util.ArrayList<>();

            for (GenTable table : tablesToSync) {
                GenTable existingTable = genTableService.selectGenTableByName(table.getTableName());
                if (existingTable != null) {
                    // 表已存在，执行同步更新
                    existingTables.add(table.getTableName());
                    // 这里可以调用同步方法更新表结构
                    genTableService.synchDb(table.getTableName());
                } else {
                    // 新表，添加到导入列表
                    newTables.add(table);
                }
            }

            // 导入新表
            if (!newTables.isEmpty()) {
                genTableService.importGenTable(newTables);
            }

            String message = String.format("同步完成！新增表: %d 个，更新表: %d 个",
                    newTables.size(), existingTables.size());

            return success(message);

        } catch (Exception e) {
            logger.error("同步表结构异常", e);
            return error("同步失败: " + e.getMessage());
        }
    }

    /**
     * 同步表结构请求对象
     */
    public static class SyncTableStructureRequest {
        private ExternalDbConfig dbConfig;
        private String[] tableNames;

        public ExternalDbConfig getDbConfig() {
            return dbConfig;
        }

        public void setDbConfig(ExternalDbConfig dbConfig) {
            this.dbConfig = dbConfig;
        }

        public String[] getTableNames() {
            return tableNames;
        }

        public void setTableNames(String[] tableNames) {
            this.tableNames = tableNames;
        }
    }

    /**
     * 导入外部表请求对象
     */
    public static class ImportExternalTablesRequest {
        @Valid
        private ExternalDbConfig dbConfig;

        private String[] tableNames;

        public ExternalDbConfig getDbConfig() {
            return dbConfig;
        }

        public void setDbConfig(ExternalDbConfig dbConfig) {
            this.dbConfig = dbConfig;
        }

        public String[] getTableNames() {
            return tableNames;
        }

        public void setTableNames(String[] tableNames) {
            this.tableNames = tableNames;
        }
    }
}
